﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using HengTong.Model;
using HengTong.Model._Admin;
using HengTong.Model.Db.Hr;
using HengTong.Model.Db.Hr.Bill;
using HengTong.Model.Db.System;
using HengTong.Model.Services;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using TiaoTaoHelper.Extension.Object;
using TiaoTaoHelper.Wtm.Models;
using UUIDNext;
using WalkingTec.Mvvm.Core;
using WalkingTec.Mvvm.Core.Extensions;


namespace HengTong.ViewModel.Person.SysPersonVms;

public partial class SysPersonBatchVm
{
    //批量删除
    public async Task<bool> DoBatchDeleteAsync()
    {
        if (Ids == null || !Ids.Any())
        {
            MSD.AddModelError(" ", "请选择要删除的员工档案");
            return false;
        }

        var transaction = await DC.Database.BeginTransactionAsync();
        try
        {
            // 将string ID转换为Guid?列表以匹配子表的PersonId类型
            var ids = Ids.Select(x => (Guid?)Guid.Parse(x)).ToList();

            // 删除所有相关的子表数据前，先删除附件
            // 删除员工合同的附件
            var contractIds = await DC.Set<SysPersonContract>()
                .Where(e => e.PersonId.HasValue && ids.Contains(e.PersonId))
                .Select(c => c.ID)
                .ToListAsync();
            if (contractIds.Any())
            {
                await DC.Set<SysPersonContractFile>()
                    .Where(a => contractIds.Contains((Guid)a.PersonContractId))
                    .ExecuteDeleteAsync();
            }

            // 删除学历附件表
            var educationIds = await DC.Set<SysPersonEducation>()
                .Where(e => e.PersonId.HasValue && ids.Contains(e.PersonId))
                .Select(e => e.ID)
                .ToListAsync();

            if (educationIds.Any())
            {
                await DC.Set<SysPersonEducationFile>()
                    .Where(f => educationIds.Contains((Guid)f.PersonEducationId))
                    .ExecuteDeleteAsync();
            }

            // 删除所有相关的子表数据
            await DC.Set<SysPersonEducation>().Where(e => e.PersonId.HasValue && ids.Contains(e.PersonId))
                .ExecuteDeleteAsync();
            await DC.Set<SysPersonFamily>().Where(e => e.PersonId.HasValue && ids.Contains(e.PersonId))
                .ExecuteDeleteAsync();
            await DC.Set<SysPersonWork>().Where(e => e.PersonId.HasValue && ids.Contains(e.PersonId))
                .ExecuteDeleteAsync();
            await DC.Set<SysPersonTrainExam>().Where(e => e.PersonId.HasValue && ids.Contains(e.PersonId))
                .ExecuteDeleteAsync();
            await DC.Set<SysPersonMedical>().Where(e => e.PersonId.HasValue && ids.Contains(e.PersonId))
                .ExecuteDeleteAsync();
            await DC.Set<SysPersonResume>().Where(e => e.PersonId.HasValue && ids.Contains(e.PersonId))
                .ExecuteDeleteAsync();
            await DC.Set<SysPersonContract>().Where(e => e.PersonId.HasValue && ids.Contains(e.PersonId))
                .ExecuteDeleteAsync();
            await DC.Set<SysPersonProfessionalTitle>().Where(e => e.PersonId.HasValue && ids.Contains(e.PersonId))
                .ExecuteDeleteAsync();

            // 删除主表数据
            var mainIds = Ids.Select(Guid.Parse).ToList();
            await DC.Set<SysPerson>().Where(p => mainIds.Contains(p.ID)).ExecuteDeleteAsync();
            await DC.SaveChangesAsync();

            await transaction.CommitAsync();
            return true;
        }
        catch (Exception e)
        {
            await transaction.RollbackAsync();
            MSD.AddModelError(" ", $"批量删除异常：{e.Message}");
            return false;
        }
        finally
        {
            await transaction.DisposeAsync();
        }
    }

    // 批量操作的员工生成系统账号
    public async Task<TiaoTaoHelper.Models.Result<int>> CreateAccountsAsync()
    {
        if (Ids == null || !Ids.Any())
        {
            return new TiaoTaoHelper.Models.Result<int>("请选择要生成账号的员工档案");
        }

        var transaction = await DC.Database.BeginTransactionAsync();
        int successCount = 0;
        var ids = Ids.Select(Guid.Parse).ToList();
        try
        {
            // 获取所有选中的员工档案信息
            var persons = await DC.Set<SysPerson>()
                .AsNoTracking()
                .Where(p => ids.Contains(p.ID))
                .ToListAsync();

            if (!persons.Any())
            {
                return new TiaoTaoHelper.Models.Result<int>("未找到有效的员工档案");
            }

            // 获取所有员工工号和手机号，用于批量检查重复
            var allStaffNos = persons.Select(p => p.StaffNo).Where(no => !string.IsNullOrEmpty(no)).ToList();
            var allPhones = persons.Select(p => p.Phone).Where(phone => !string.IsNullOrEmpty(phone)).ToList();

            // 检查工号是否已有关联账号
            var existingUsers = await DC.Set<FrameworkUser>()
                .AsNoTracking()
                .Where(u => allStaffNos.Contains(u.ITCode))
                .Select(u => u.ITCode)
                .ToListAsync();

            // 检查手机号是否已被使用
            var existingPhones = await DC.Set<FrameworkUser>()
                .AsNoTracking()
                .Where(u => allPhones.Contains(u.CellPhone))
                .Select(u => u.CellPhone)
                .ToListAsync();

            // 批量创建账号
            foreach (var person in persons)
            {
                // 检查是否填写手机号
                if (string.IsNullOrWhiteSpace(person.Phone) || person.Phone.Trim().Length != 11)
                {
                    return new TiaoTaoHelper.Models.Result<int>($"员工 {person.Name}({person.StaffNo}) 的手机号不正确");
                }

                // 检查是否已存在账号
                if (existingUsers.Contains(person.StaffNo))
                {
                    return new TiaoTaoHelper.Models.Result<int>($"员工 {person.Name}({person.StaffNo}) 的账号已存在");
                }

                // 检查账号是否有关联的手机号
                if (existingPhones.Contains(person.Phone))
                {
                    return new TiaoTaoHelper.Models.Result<int>($"员工 {person.Name} 的手机号 {person.Phone} 已关联其他账号");
                }

                // 创建新账号
                var newUser = new FrameworkUser
                {
                    ID = Uuid.NewDatabaseFriendly(Database.SqlServer),
                    ITCode = person.StaffNo,
                    Name = person.Name,
                    CellPhone = person.Phone,
                    GroupId = person.GroupId,
                    Password = Utils.GetMD5String(Uuid.NewDatabaseFriendly(Database.SqlServer).ToString()), // 生成随机密码
                    PersonId = person.ID,
                    CreateBy = Wtm.LoginUserInfo?.ITCode,
                    UpdateBy = Wtm.LoginUserInfo?.ITCode,
                    CreateTime = DateTime.Now,
                    UpdateTime = DateTime.Now
                };

                // 添加账号到数据库
                await DC.Set<FrameworkUser>().AddAsync(newUser);
                successCount++;
            }

            if (successCount > 0)
            {
                await DC.SaveChangesAsync();
                await transaction.CommitAsync();
                return new TiaoTaoHelper.Models.Result<int>()
                {
                    Data = successCount,
                    Message = $"{successCount} 个账号创建成功"
                };
            }
            else
            {
                return new TiaoTaoHelper.Models.Result<int>("创建账号失败");
            }
        }
        catch (Exception e)
        {
            await transaction.RollbackAsync();
            return new TiaoTaoHelper.Models.Result<int>("创建账号失败");
        }
        finally
        {
            await transaction.DisposeAsync();
        }
    }


    /// <summary>
    /// 通过查询条件生成人员补录数据
    /// </summary>
    /// <returns>生成的数据数量</returns>
    public async Task<TiaoTaoHelper.Models.Result<int>> GenSuppBySearchAsync(SysPersonSearcher searcher)
    {
        var query = await DC.Set<SysPerson>()
            .Where(x => x.GetType() == typeof(SysPerson))
            .CheckContain(searcher.Name, x => x.Name)
            .CheckContain(searcher.StaffNo, x => x.StaffNo)
            .CheckBetween(searcher.BirthDate?.GetStartTime(), searcher.BirthDate?.GetEndTime(), x => x.BirthDate,
                includeMax: false)
            .CheckEqual(searcher.Age, x => x.Age)
            .CheckEqual(searcher.Gender, x => x.Gender)
            .CheckEqual(searcher.Ethnicity, x => x.Ethnicity)
            .CheckEqual(searcher.HighestEducation, x => x.HighestEducation)
            .CheckEqual(searcher.MaritalStatus, x => x.MaritalStatus)
            .CheckContain(searcher.IdCardNo, x => x.IdCardNo)
            .CheckContain(searcher.HouseholdRegistration, x => x.HouseholdRegistration)
            .CheckContain(searcher.NativePlace, x => x.NativePlace)
            .CheckEqual(searcher.PoliticalStatus, x => x.PoliticalStatus)
            .CheckContain(searcher.ArchiveLocation, x => x.ArchiveLocation)
            .CheckContain(searcher.HomeAddress, x => x.HomeAddress)
            .CheckContain(searcher.Phone, x => x.Phone)
            .CheckEqual(searcher.OrgId, x => x.OrgId)
            .CheckEqual(searcher.GroupId, x => x.GroupId)
            .CheckEqual(searcher.JobPositionId, x => x.JobPositionId)
            .CheckBetween(searcher.HireDate?.GetStartTime(), searcher.HireDate?.GetEndTime(), x => x.HireDate,
                includeMax: false)
            .CheckEqual(searcher.EmploymentType, x => x.EmploymentType)
            .CheckEqual(searcher.ContractType, x => x.ContractType)
            .CheckContain(searcher.ContractNo, x => x.ContractNo)
            .CheckEqual(searcher.State, x => x.State)
            .CheckEqual(searcher.BloodType, x => x.BloodType)
            .Include(x => x.PersonEducations).ThenInclude(e => e.Attachments)
            .Include(x => x.PersonFamilies)
            .Include(x => x.PersonWorks)
            .Include(x => x.PersonResumes)
            .Include(x => x.PersonProfessionalTitles)
            .AsNoTracking()
            .ToArrayAsync();

        if (!query.Any())
        {
            return new TiaoTaoHelper.Models.Result<int>("未找到符合条件的人员档案");
        }

        // 批量检查是否已存在补录单，WorkflowStatus 状态为:待提交 = 0,提交中 = 5,审核中 = 10
        var staffNos = query.Select(p => p.StaffNo).Where(s => !string.IsNullOrEmpty(s)).ToList();
        var existingBills = await DC.Set<SysPersonRepairBill>()
            .AsNoTracking()
            .Where(b => staffNos.Contains(b.StaffNo) &&
                        (b.WorkflowStatus == WorkflowStatus.待提交 ||
                         b.WorkflowStatus == WorkflowStatus.提交中 ||
                         b.WorkflowStatus == WorkflowStatus.审核中))
            .Select(b => new { b.StaffNo, b.WorkflowStatus })
            .ToListAsync();
        if (existingBills.Any())
        {
            var existingStaffNos = existingBills.Select(b => b.StaffNo).ToHashSet();
            var conflictPersons = query.Where(p => existingStaffNos.Contains(p.StaffNo)).ToList();

            var errorMessages = conflictPersons.Select((p, index) =>
            {
                var bill = existingBills.First(b => b.StaffNo == p.StaffNo);
                return $"{index + 1}. 员工 {p.Name}({p.StaffNo}) 已存在状态为'{bill.WorkflowStatus}'的补录单";
            }).ToList();

            return new TiaoTaoHelper.Models.Result<int>(
                $"以下人员已存在未完成的补录单，请先处理：\n{string.Join("\n", errorMessages)}");
        }

        var transaction = await DC.Database.BeginTransactionAsync();
        int successCount = 0;

        try
        {
            successCount = await GeneratePersonRepairBillsAsync(query);

            if (successCount > 0)
            {
                await DC.SaveChangesAsync();
                await transaction.CommitAsync();
                return new TiaoTaoHelper.Models.Result<int>
                {
                    Data = successCount,
                    Message = $"{successCount} 条补录数据生成成功"
                };
            }
            else
            {
                await transaction.RollbackAsync();
                return new TiaoTaoHelper.Models.Result<int>("未找到符合条件的人员档案");
            }
        }
        catch (Exception ex)
        {
            await transaction.RollbackAsync();
            return new TiaoTaoHelper.Models.Result<int>($"生成补录数据失败：{ex.Message}");
        }
        finally
        {
            await transaction.DisposeAsync();
        }
    }


    /// <summary>
    /// 通过勾选ID生成人员补录数据
    /// </summary>
    /// <returns>生成的数据数量</returns>
    public async Task<TiaoTaoHelper.Models.Result<int>> GenSuppByIdsAsync()
    {
        if (Ids == null || !Ids.Any())
        {
            return new TiaoTaoHelper.Models.Result<int>("请选择需要生成补录数据的人员档案");
        }

        var ids = Ids.Select(Guid.Parse).ToList();

        var query = await DC.Set<SysPerson>()
            .Where(p => ids.Contains(p.ID))
            .Where(x => x.GetType() == typeof(SysPerson))
            .Include(x => x.PersonEducations).ThenInclude(e => e.Attachments)
            .Include(x => x.PersonFamilies)
            .Include(x => x.PersonWorks)
            .Include(x => x.PersonResumes)
            .Include(x => x.PersonProfessionalTitles)
            .AsNoTracking()
            .ToArrayAsync();

        if (!query.Any())
        {
            return new TiaoTaoHelper.Models.Result<int>("未找到有效的人员档案");
        }

        // 批量检查是否已存在补录单，WorkflowStatus 状态为:待提交 = 0,提交中 = 5,审核中 = 10
        var staffNos = query.Select(p => p.StaffNo).Where(s => !string.IsNullOrEmpty(s)).ToList();
        var existingBills = await DC.Set<SysPersonRepairBill>()
            .AsNoTracking()
            .Where(b => staffNos.Contains(b.StaffNo) &&
                        (b.WorkflowStatus == WorkflowStatus.待提交 ||
                         b.WorkflowStatus == WorkflowStatus.提交中 ||
                         b.WorkflowStatus == WorkflowStatus.审核中))
            .Select(b => new { b.StaffNo, b.WorkflowStatus })
            .ToListAsync();
        if (existingBills.Any())
        {
            var existingStaffNos = existingBills.Select(b => b.StaffNo).ToHashSet();
            var conflictPersons = query.Where(p => existingStaffNos.Contains(p.StaffNo)).ToList();

            var errorMessages = conflictPersons.Select((p, index) =>
            {
                var bill = existingBills.First(b => b.StaffNo == p.StaffNo);
                return $"{index + 1}. 员工 {p.Name}({p.StaffNo}) 已存在状态为'{bill.WorkflowStatus}'的补录单";
            }).ToList();

            return new TiaoTaoHelper.Models.Result<int>(
                $"以下人员已存在未完成的补录单，请先处理：\n{string.Join("\n", errorMessages)}");
        }


        var transaction = await DC.Database.BeginTransactionAsync();
        int successCount = 0;
        try
        {
            successCount = await GeneratePersonRepairBillsAsync(query);

            if (successCount > 0)
            {
                await DC.SaveChangesAsync();
                await transaction.CommitAsync();
                return new TiaoTaoHelper.Models.Result<int>
                {
                    Data = successCount,
                    Message = $"{successCount} 条补录数据生成成功"
                };
            }
            else
            {
                await transaction.RollbackAsync();
                return new TiaoTaoHelper.Models.Result<int>("生成补录数据失败");
            }
        }
        catch (Exception ex)
        {
            await transaction.RollbackAsync();
            return new TiaoTaoHelper.Models.Result<int>($"生成补录数据失败：{ex.Message}");
        }
        finally
        {
            await transaction.DisposeAsync();
        }
    }


    /// <summary>
    /// 生成人员补录数据的公共方法（批量优化版本）
    /// </summary>
    /// <param name="persons">人员档案数据</param>
    /// <returns>成功生成的数量</returns>
    private async Task<int> GeneratePersonRepairBillsAsync(SysPerson[] persons)
    {
        // 批量数据集合
        var bills = new List<SysPersonRepairBill>();
        var educations = new List<SysPersonEducation>();
        var families = new List<SysPersonFamily>();
        var works = new List<SysPersonWork>();
        var resumes = new List<SysPersonResume>();
        var professionalTitles = new List<SysPersonProfessionalTitle>();

        var currentTime = DateTime.Now;
        var currentUser = Wtm.LoginUserInfo?.ITCode;

        foreach (var person in persons)
        {
            // 为每个编码生成创建独立的作用域
            using var scope = Wtm.ServiceProvider.CreateScope();
            var service = scope.ServiceProvider.GetRequiredService<CodeGeneratorService>();

            var bill = new SysPersonRepairBill();
            person.CloneMatchingProperties(bill);

            bill.ID = Uuid.NewDatabaseFriendly(Database.SqlServer); // 确保在CloneMatchingProperties之后重新设置ID
            // 立即清空导航属性，防止EF追踪
            bill.PersonEducations = new List<SysPersonEducation>();
            bill.PersonFamilies = new List<SysPersonFamily>();
            bill.PersonWorks = new List<SysPersonWork>();
            bill.PersonResumes = new List<SysPersonResume>();
            bill.PersonProfessionalTitles = new List<SysPersonProfessionalTitle>();

            bill.BillStatus ??= BillStatus.草稿;
            bill.WorkflowStatus ??= WorkflowStatus.待提交;
            bill.CreateTime = currentTime;
            bill.UpdateTime = currentTime;
            bill.CreateBy = person.StaffNo;
            bill.UpdateBy = person.StaffNo;

            var code = await service.GenerateCodeAsync(bill.GetType().Name);
            if (code == null)
            {
                MSD.AddModelError(" ", $"生成编码失败，请检查编码生成配置");
                return 0;
            }

            bill.BillCode = code;
            bills.Add(bill);

            // 处理学习经历
            foreach (var item in person.PersonEducations)
            {
                var newEducation = new SysPersonEducation();
                item.CloneMatchingProperties(newEducation);
                newEducation.ID = Uuid.NewDatabaseFriendly(Database.SqlServer); // 在CloneMatchingProperties之后重新设置ID
                newEducation.PersonId = bill.ID;
                newEducation.Person = null;
                newEducation.CreateTime = currentTime;
                newEducation.UpdateTime = currentTime;
                newEducation.CreateBy = currentUser;
                newEducation.UpdateBy = currentUser;

                // 复制附件信息
                if (item.Attachments?.Any() == true)
                {
                    newEducation.Attachments = item.Attachments.Select(att =>
                    {
                        var newAttachment = new SysPersonEducationFile();
                        att.CloneMatchingProperties(newAttachment);
                        newAttachment.ID = Uuid.NewDatabaseFriendly(Database.SqlServer);
                        newAttachment.PersonEducationId = newEducation.ID;
                        return newAttachment;
                    }).ToList();
                }

                educations.Add(newEducation);
            }

            // 处理家庭成员
            foreach (var item in person.PersonFamilies)
            {
                var newFamily = new SysPersonFamily();
                item.CloneMatchingProperties(newFamily);
                newFamily.ID = Uuid.NewDatabaseFriendly(Database.SqlServer); // 在CloneMatchingProperties之后重新设置ID
                newFamily.PersonId = bill.ID;
                newFamily.Person = null;
                newFamily.CreateTime = currentTime;
                newFamily.UpdateTime = currentTime;
                newFamily.CreateBy = currentUser;
                newFamily.UpdateBy = currentUser;
                families.Add(newFamily);
            }

            // 处理工作经历
            foreach (var item in person.PersonWorks)
            {
                var newWork = new SysPersonWork();
                item.CloneMatchingProperties(newWork);
                newWork.ID = Uuid.NewDatabaseFriendly(Database.SqlServer); // 在CloneMatchingProperties之后重新设置ID
                newWork.PersonId = bill.ID;
                newWork.Person = null;
                newWork.CreateTime = currentTime;
                newWork.UpdateTime = currentTime;
                newWork.CreateBy = currentUser;
                newWork.UpdateBy = currentUser;
                works.Add(newWork);
            }

            // 处理员工履历
            foreach (var item in person.PersonResumes)
            {
                var newResume = new SysPersonResume();
                item.CloneMatchingProperties(newResume);
                newResume.ID = Uuid.NewDatabaseFriendly(Database.SqlServer); // 在CloneMatchingProperties之后重新设置ID
                newResume.PersonId = bill.ID;
                newResume.Person = null;
                newResume.CreateTime = currentTime;
                newResume.UpdateTime = currentTime;
                newResume.CreateBy = currentUser;
                newResume.UpdateBy = currentUser;
                resumes.Add(newResume);
            }

            // 处理荣誉职称
            foreach (var item in person.PersonProfessionalTitles)
            {
                var newTitle = new SysPersonProfessionalTitle();
                item.CloneMatchingProperties(newTitle);
                newTitle.ID = Uuid.NewDatabaseFriendly(Database.SqlServer); // 在CloneMatchingProperties之后重新设置ID
                newTitle.PersonId = bill.ID;
                newTitle.Person = null;
                newTitle.CreateTime = currentTime;
                newTitle.UpdateTime = currentTime;
                newTitle.CreateBy = currentUser;
                newTitle.UpdateBy = currentUser;
                professionalTitles.Add(newTitle);
            }
        }

        // 批量添加到数据库
        if (bills.Any()) await DC.Set<SysPersonRepairBill>().AddRangeAsync(bills);
        if (educations.Any()) await DC.Set<SysPersonEducation>().AddRangeAsync(educations);
        if (families.Any()) await DC.Set<SysPersonFamily>().AddRangeAsync(families);
        if (works.Any()) await DC.Set<SysPersonWork>().AddRangeAsync(works);
        if (resumes.Any()) await DC.Set<SysPersonResume>().AddRangeAsync(resumes);
        if (professionalTitles.Any()) await DC.Set<SysPersonProfessionalTitle>().AddRangeAsync(professionalTitles);

        return bills.Count;
    }

    /// <summary>
    /// 批量生成岗位分配申请
    /// </summary>
    /// <returns>生成的岗位分配申请主表ID</returns>
    public async Task<TiaoTaoHelper.Models.Result<Guid>> BatchAssignJobsAsync()
    {
        var logger = Wtm.ServiceProvider.GetRequiredService<ILogger<SysPersonBatchVm>>();

        if (Ids == null || !Ids.Any())
        {
            return new TiaoTaoHelper.Models.Result<Guid>("请选择需要分配岗位的员工档案");
        }

        var ids = Ids.Select(Guid.Parse).ToList();
        logger.LogInformation("准备生成岗位分配申请，员工数量：{Count}", ids.Count);

        // 使用事务确保数据一致性
        using var transaction = await DC.Database.BeginTransactionAsync();
        try
        {
            // 查询人员档案数据
            var persons = await DC.Set<SysPerson>()
                .Where(p => ids.Contains(p.ID))
                .Include(p => p.Group) // 包含部门信息
                .Include(p => p.JobPosition) // 包含岗位信息
                .Include(p => p.Org) // 包含公司信息
                .ToListAsync();

            if (!persons.Any())
            {
                return new TiaoTaoHelper.Models.Result<Guid>("未找到有效的员工档案");
            }

            // 验证员工档案完整性
            var validationResult = await ValidatePersonDataAsync(persons);
            if (!validationResult.IsSuccess)
            {
                return new TiaoTaoHelper.Models.Result<Guid>(validationResult.Message);
            }

            // 校验OrgId是否一致
            /*var orgIds = persons.Select(p => p.OrgId).Distinct().Where(id => id.HasValue).ToList();
            if (orgIds.Count > 1)
            {
                return new TiaoTaoHelper.Models.Result<Guid>("选中的员工包含不同的公司，请选择相同公司的员工进行批量操作");
            }

            if (!orgIds.Any() || !orgIds.First().HasValue)
            {
                return new TiaoTaoHelper.Models.Result<Guid>("选中的员工未设置公司，无法进行批量操作");
            }*/

            // 获取当前用户所属的第一个公司ID
            var currentUserId = Guid.Parse(Wtm.LoginUserInfo.UserId);
            var orgId = await DC.Set<SysUserJobPosition>()
                .Where(ujp => ujp.UserId == currentUserId && ujp.JobPositionId.HasValue)
                .Join(DC.Set<SysJobPosition>(),
                    ujp => ujp.JobPositionId.Value,
                    jp => jp.ID,
                    (ujp, jp) => jp)
                .SelectMany(jp => jp.Organizations.Select(o => o.OrgId))
                .Where(id => id.HasValue)
                .FirstOrDefaultAsync();

            // 生成岗位分配申请单主表
            var assignmentBill = new SysHrJobAssignmentRequestBill
            {
                ID = Uuid.NewDatabaseFriendly(Database.SqlServer),
                GroupId = Wtm.LoginUserInfo?.Groups?.FirstOrDefault()?.ID,
                OrgId = orgId,
                BillStatus = BillStatus.草稿,
                WorkflowStatus = WorkflowStatus.待提交,
                CreateTime = DateTime.Now,
                UpdateTime = DateTime.Now,
                CreateBy = Wtm.LoginUserInfo?.ITCode,
                UpdateBy = Wtm.LoginUserInfo?.ITCode
            };

            // 生成编码
            var codeService = Wtm.ServiceProvider.GetRequiredService<CodeGeneratorService>();
            assignmentBill.BillCode = await codeService.GenerateCodeAsync(assignmentBill.GetType().Name);

            // 若编码生成失败，终止操作
            if (string.IsNullOrEmpty(assignmentBill.BillCode))
            {
                return new TiaoTaoHelper.Models.Result<Guid>("生成岗位分配申请单号失败，请联系系统管理员");
            }

            assignmentBill.Remark = $"批量分配岗位，涉及{persons.Count}名待入职员工";

            // 创建子表记录
            var entries = persons.Select(p => new SysHrJobAssignmentRequestBillEntry
            {
                ID = Uuid.NewDatabaseFriendly(Database.SqlServer),
                JobAssignmentId = assignmentBill.ID,
                PersonId = p.ID,
                StaffNo = p.StaffNo,
                Name = p.Name,

                OrgId = p.OrgId,
                GroupId = p.GroupId,
                JobPositionId = p.JobPositionId,

                CreateTime = DateTime.Now,
                UpdateTime = DateTime.Now,
                CreateBy = p.StaffNo,
                UpdateBy = Wtm.LoginUserInfo?.ITCode
            }).ToList();

            // 保存到数据库
            await DC.Set<SysHrJobAssignmentRequestBill>().AddAsync(assignmentBill);
            await DC.Set<SysHrJobAssignmentRequestBillEntry>().AddRangeAsync(entries);
            await DC.SaveChangesAsync();

            // 提交事务
            await transaction.CommitAsync();

            logger.LogInformation("岗位分配申请生成成功，ID：{Id}，员工数量：{Count}", assignmentBill.ID, persons.Count);

            return new TiaoTaoHelper.Models.Result<Guid>
            {
                Data = assignmentBill.ID,
                Message = $"岗位分配申请生成成功，包含 {persons.Count} 名员工，申请单号为：{assignmentBill.BillCode}"
            };
        }
        catch (Exception ex)
        {
            await transaction.RollbackAsync();
            logger.LogError(ex, "生成岗位分配申请失败");
            return new TiaoTaoHelper.Models.Result<Guid>($"生成失败：{ex.Message}");
        }
    }

    /// <summary>
    /// 验证人员数据完整性
    /// </summary>
    /// <param name="persons">人员列表</param>
    /// <returns>验证结果</returns>
    private async Task<(bool IsSuccess, string Message)> ValidatePersonDataAsync(List<SysPerson> persons)
    {
        var invalidPersons = new List<string>();

        foreach (var person in persons)
        {
            // 检查员工是否为待入职状态
            if (person.State != PersonState.待入职)
            {
                invalidPersons.Add($"员工 {person.Name}({person.StaffNo ?? "无工号"}) 不是待入职状态，当前状态为：{person.State}");
                continue;
            }

            // 检查员工是否已经在其他岗位分配流程中
            var existingEntry = await DC.Set<SysHrJobAssignmentRequestBillEntry>()
                .Include(e => e.JobAssignment)
                .Where(e => e.PersonId == person.ID &&
                            e.JobAssignment.WorkflowStatus != WorkflowStatus.已完成 &&
                            e.JobAssignment.WorkflowStatus != WorkflowStatus.已取消)
                .Select(e => e.JobAssignment.BillCode)
                .FirstOrDefaultAsync();

            if (!string.IsNullOrEmpty(existingEntry))
            {
                invalidPersons.Add($"员工 {person.Name}({person.StaffNo ?? "无工号"}) 已存在于未完成的岗位分配流程中，单号：{existingEntry}");
            }
        }

        if (invalidPersons.Any())
        {
            return (false, $"以下员工不能进行岗位分配：\n{string.Join("\n", invalidPersons)}");
        }

        return (true, string.Empty);
    }
}